<template>
  <div>
    <div class="step-wrap">
      <el-steps :space="200" :active="active" finish-status="success" align-center v-if="form.isPublish === '0'">
        <el-step title="创建MR"></el-step>
        <el-step title="代码审查"></el-step>
        <el-step title="合并分支"></el-step>
        <el-step title="Jenkins构建"></el-step>
      </el-steps>
      <el-steps :space="200" :active="active" finish-status="success" align-center v-else>
        <el-step title="合并master"></el-step>
        <el-step title="创建MR"></el-step>
        <el-step title="代码审查" v-if="form.isReviewing == '1'"></el-step>
        <el-step title="合并分支"></el-step>
        <el-step title="Jenkins构建"></el-step>
      </el-steps>
    </div>
    <div class="form-wrap">
      <el-form ref="formRef" :model="form" :rules="rules" label-width="150px">
        <el-form-item label="工程" prop="project">
          {{ form.project }}
          <el-select v-model="form.project">
            <el-option v-for="item in projectsOptions" :key="item.value" :value="item.value" :label="item.label"> </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="版本号" prop="version">
          <el-select v-model="form.version">
            <el-option v-for="item in branchsOptions" :key="item.value" :value="item.value" :label="item.label"> </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="合并" prop="test"> test </el-form-item>
        <el-form-item label="有版本发布" prop="isPublish">
          <el-radio v-model="form.isPublish" label="1">是</el-radio>
          <el-radio v-model="form.isPublish" label="0">否</el-radio>
        </el-form-item>
        <el-form-item label="上一次发布的版本号" prop="prePublishVersion" v-if="form.isPublish !== '1'">
          <el-select v-model="form.prePublishVersion">
            <el-option v-for="item in branchsOptions" :key="item.value" :value="item.value" :label="item.label"> </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="合并到master的分支" prop="preMergeVersion" v-if="form.isPublish !== '1'">
          {{ preMergeVersion }}
        </el-form-item>
        <el-form-item label="是否审核代码" prop="isReviewing">
          <el-radio v-model="form.isReviewing" :label="1">是</el-radio>
          <el-radio v-model="form.isReviewing" :label="0">否</el-radio>
        </el-form-item>
        
        <el-form-item label="Jenkins自动构建" prop="autoBuild">
          <el-switch v-model="jenkinsConfig.enabled" active-text="启用" inactive-text="禁用"></el-switch>
        </el-form-item>
         <el-form-item label="Jenkins自动构建" prop="autoBuild">
          <el-input v-model="jenkinsConfig.crumb" placeholder="请输入构建参数"></el-input>
          <el-input v-model="jenkinsConfig.Cookie" placeholder="请输入构建参数"></el-input>
        </el-form-item>
      </el-form>
      <div v-if="testBranchName" style="margin-top: 20px; color: red; font-weight: 700">测试分支：{{ testBranchName }}</div>
    </div>

    <div style="margin-top: 20px; color: red; font-weight: 700">测试分支：{{ testBranchName }}</div>
    <div class="footer">
      <el-button type="primary" @click="onPubilshTest" :loading="isLoading">打包测试版</el-button>
      <el-button v-if="form.isPublish === '1'" disabled>打包正式版</el-button>
      <el-button type="primary" @click="onBuildJenkins" >jenkines</el-button>
      <!-- </el-tooltip> -->
    </div>
    <el-dialog title="审查结果" v-model="checklistVisible" center>
      <p v-html="reviewResults.replaceAll('\n', '<br>')"></p>
    </el-dialog>
  </div>
</template>

<script setup>
import { findProjects, findBranchsByProject, createMergeRequest, acceptMergeRequest, findTagsByProject, createTagByProject, closeMergeRequest, removeTagByProject, findMergeRequest, findMergeRequestList, findCompareByProject, findMergeRequestChanges, postReviewComment, postReviewIssuse, findMergeRequestDetail } from './api/index.js'
import { ref, reactive, watch, onMounted, computed, toRaw } from 'vue'
import { ElMessage } from 'element-plus'
import { deepseekApi } from './api/deepAxios.js'
import { getLineObj, getDiffBlocks, delay } from '@/scripts/utils.js'
import JenkinsService from '@/services/JenkinsService.js'

// 项目映射配置
const projectMap = new Map([
  ['1854', 'contract-center-platform-vue'],
  ['1864', 'contract-tenant-service-vue'],
  ['2727', 'scm-tenant-h5-vue'],
]);



// 硅基流动DeepSeek代码审查服务 - 优化版本
class DeepSeekService {
  constructor() {}

  // 发送代码审查请求
  async requestCodeReview(code) {
    try {
      const response = await deepseekApi.post('/chat/completions', {
        model: 'deepseek-ai/DeepSeek-V3',
        messages: [
          {
            role: 'system',
            content: '你是一个专业的代码审查助手，提供详细、结构化的中文审查报告，根据File：文件路径，给出每个变动代码的问题和建议。包括总体评价、问题分类、改进建议和评分。',
          },
          {
            role: 'user',
            content: code,
          },
        ],
        temperature: 0.1,
        max_tokens: 10000,
      })

      return response.data.choices[0].message.content
    } catch (error) {
      throw new Error('DeepSeek分析失败: ' + error.message)
    }
  }

  // 格式化diff数据为DeepSeek API需要的格式
  formatDiffData(mergeRequestData) {
    if (!mergeRequestData || !mergeRequestData.changes) {
      return ''
    }

    return mergeRequestData.changes
      .map(change => {
        return `File: ${change.new_path}\n${change.diff}`
      })
      .join('\n\n')
  }

  // 显示代码审查结果
  showReviewResult(result) {
    if (!result || !result.review_comments) {
      ElMessage.info('代码审查完成，未发现问题')
      return
    }

    const dialogContent = result.review_comments
      .map(comment => {
        return `\n[${comment.severity}] ${comment.file_path}:${comment.line_number}\n${comment.comment}`
      })
      .join('')
  }

  shouldReviewFile(filePath) {
    const ignorePatterns = [/\.md$/i, /\.json$/i, /\.yml$/i, /\.yaml$/i, /package-lock\.json$/i, /yarn\.lock$/i, /\.gitignore$/i, /\.env/, /dist\//, /node_modules\//]
    return !ignorePatterns.some(pattern => pattern.test(filePath))
  }
}

const form = ref({
  version: '',
  project: '',
  isPublish: '1', // 是否之前有版本发布
  testSetVersion: 'development_TestSet',
  isTestSet: '1',
  isReviewing: 0,
  prePublishVersion: '',
})
const reviewResults = ref('')
const reviewResultsArr = ref([])
const isReviewing = ref(0)
const formRef = ref()
const checklistVisible = ref(false)
const isLoading = ref(false)
const isPublishLoading = ref(false)
const active = ref(0)
const testBranchName = ref('')
const projectsOptions = ref([]) // 项目列表
const branchsOptions = ref([]) // 分支列表
const rules = {
  project: [{ required: true, message: '请选择项目', trigger: 'change' }],
  version: [{ required: true, message: '请输入版本号', trigger: 'blur' }],
  isPublish: [{ required: true, message: '请选择发布类型', trigger: 'change' }],
}

const versionNum = ref('dev_WH25.6.2_1')

const checklistOptions = ref([
  { label: '请求前缀配置确认（api文件夹下面，config.js文件中production配置）', value: '1' },
  { label: 'Master分支已经合并到当前版本', value: '2' },
])

// Jenkins配置选项
const jenkinsConfig = reactive({
  enabled: true, // 是否启用自动构建
  autoTrigger: true, // 合并完成后自动触发
  waitForBuild: false, // 是否等待构建完成
  crumb: 'a47fdd3aec30dc0df529786fa42cf9c2e80a971183e4a3d19644b19372e98718', // Jenkinscrumb
  Cookie: 'jenkins-timestamper-offset=-28800000; jenkins-timestamper=system; jenkins-timestamper-local=true; JSESSIONID=29C88372229570F0AD6877FD7926DB68; remember-me=aGVqaWFueWk6MTc1ODc4NzcyMDU2Mzo0YmIwODNlOTQ4YTE5ZjE0MGJiZWZjYjYzN2IzZmMyYmZjODlmZjEwMmU4NDYyYzM2Mjg3MjIyOWQwMThhNWJm; screenResolution=1920x1080', // JenkinsCookie



})

watch(
  () => form.value.project,
  v => {
    console.log('form', v)
    getBranchs(v)
  }
)

// 获取项目列表
const getProjects = async () => {
  const { data } = await findProjects()
  projectsOptions.value = data.map(item => ({
    label: item.name,
    value: item.id,
  }))
}

// 获取项目分支列表
const getBranchs = async projectId => {
  const { data } = await findBranchsByProject({
    projectId,
  })
  branchsOptions.value = data.map(item => {
    item.label = item.name + ` (${item.merged ? '已合并' : '未合并'})`
    item.value = item.name
    return item
  })
}

const onShowChecklist = () => {
  checklistVisible.value = true
  this.checklist = []
}

const onBuildJenkins = async () => {
  // 将数字ID转换为字符串再查询
  const projectIdStr = String(form.value.project)
  const jobName = projectMap.get(projectIdStr)
  
  const jenkinsService = new JenkinsService({
    jobName: jobName
  })
  const result = await jenkinsService.triggerBuild(jobName)
  console.log('[ projectMap.get(form.value.project) ]-236', jobName)
  console.log('[ result ]-237', result)
  if (result) {
    ElMessage.success('Jenkins构建已触发')
  } else {
    ElMessage.warning('构建触发失败，已打开Jenkins页面')
  }
}

const onPubilshTest = async () => {
  active.value = 0
  testBranchName.value = ''
  formRef.value.validate(async valid => {
    if (valid) {
      try {
        console.log('[ valid ]-146', valid)

        // if (form.value.isPublish === '1') {
        //   // 1. 最近有发布的情况下，检查master是否合并到了对应的feature分支
        //   const { data: masterMerge } = await createMergeRequest({
        //     projectId: form.value.project,
        //     source_branch: 'master',
        //     target_branch: form.value.version,
        //     title: 'merge request from master',
        //     description: `merge from master to ${form.value.version}`
        //   })
        //   if (masterMerge.changes_count) {
        //     await acceptMergeRequest({
        //       projectId: form.value.project,
        //       mrId: masterMerge.iid
        //     })
        //   } else {
        //     await closeMergeRequest({
        //       projectId: form.value.project,
        //       mrId: masterMerge.iid
        //     })
        //   }
        //   active.value++
        // }
        // 2. 建merge request
        // 合过master 直接打包
        // TODO  多版本 获取 目标 development 分支号 Testset
        // 默认 test1 分支
        const targetBranch = branchsOptions.value.filter(item => item.name.indexOf('test') === 0)
        if (targetBranch.length > 1) {
          ElMessage.error('匹配的development分支过多：' + targetBranch.length)
          isLoading.value = false
        } else if (targetBranch.length === 0) {
          ElMessage.error('没有找到对应的development分支！')
          isLoading.value = false
        } else {
          // merge request的title都会加上版本号，这里先查询有当前版本号的merge request，如果存在就不用创建merge request
          // merge request的命名规则：必须加版本号
          const { data: mergeRequests } = await findMergeRequest({
            projectId: form.value.project,
            search: form.value.version,
          })
          console.log('[ mergeRequests ]-186', mergeRequests)

          let mergeId = ''
          if (mergeRequests.length <= 0) {
            // 如果merge request不遵守规则，这边还是会出现冲突的情况
            // 冲突手动去gitlab 修复
            // feature 合并到 development
            // 先判断2个分支存在差异
            const { data: compare } = await findCompareByProject({
              projectId: form.value.project,
              from_branch: form.value.version,
              to_branch: targetBranch[0].name,
            })
            active.value++
            // 存在差异 才创建merge request
            if (compare.diffs.length > 0 || compare.commits.length > 0) {
              const { data: mrInfo } = await createMergeRequest({
                projectId: form.value.project,
                source_branch: form.value.version,
                target_branch: targetBranch[0].name,
                title: 'merge request ' + form.value.version,
                description: `merge from ${form.value.version} to ${targetBranch[0].name}`,
              })
              mergeId = mrInfo.iid
              console.log('[ compare ]-199', compare, mrInfo)
              if (!mrInfo.changes_count) {
                ElMessage.warning('当前分支没有更新！')
                await closeMergeRequest({
                  projectId: form.value.project,
                  mrId: mrInfo.iid,
                })
                isLoading.value = false
                return
              }
            } else {
              ElMessage.warning('当前分支没有更新！')
              isLoading.value = false
              return
            }
            //
            const { data: merDetail } = await findMergeRequestDetail({
              projectId: form.value.project,
              mrId: mergeId,
            })

            // 通过deepseek 查看merge request 差异并进行代码审查
            const { data: merData } = await findMergeRequestChanges({
              projectId: form.value.project,
              mrId: mergeId,
            })
            active.value++

            // 集成硅基流动DeepSeek代码审查
            const deepSeekService = new DeepSeekService()
            console.log('[ merData ]-237=====', merData)

            // 进行代码审查
            if (merData && merData.changes && merData.changes.length > 0 && form.value.isReviewing == 1) {
              ElMessage.info('正在进行代码审查，请稍候...')
              // 整体notes
              // const formattedDiff = deepSeekService.formatDiffData(merData)
              // const reviewResult = await deepSeekService.requestCodeReview(formattedDiff)
              // console.log('[ reviewResult ]-325', reviewResult)
              // if (reviewResult) {
              //   reviewResults.value = reviewResult
              //   checklistVisible.value = true
              //   // await  postReviewComment({
              //   //     projectId: form.value.project,
              //   //     mrId: mergeId,
              //   //     body: reviewResult,
              //   //   })
              //   await postReviewIssuse({
              //     projectId: form.value.project,
              //     mrId: mergeId,
              //     mrId: mergeId,
              //     sha: merDetail.sha,
              //     body: reviewResult,
              //     note: reviewResult,
              //   })
              // }
              for (const change of merData.changes) {
                if (deepSeekService.shouldReviewFile(change.new_path)) {
                  // const review = await deepSeekService.requestCodeReview(`File: ${change.new_path}\n${change.diff}`, {
                  //   filePath: change.new_path,
                  // })
                  const diffBlocks = getDiffBlocks(change?.diff)
                  while (!!diffBlocks.length) {
                    const item = diffBlocks.shift()
                    const lineRegex = /@@\s-(\d+)(?:,(\d+))?\s\+(\d+)(?:,(\d+))?\s@@/
                    const matches = lineRegex.exec(item)
                    if (matches) {
                      const lineObj = getLineObj(matches, item)
                      if ((lineObj?.new_line && lineObj?.new_line > 0) || (lineObj.old_line && lineObj.old_line > 0)) {
                        try {
                          const suggestion = await deepSeekService.requestCodeReview(`File: ${change.new_path}\n${change.diff}`, { filePath: change.new_path })
                          // const suggestion =2222
                          if (suggestion) {
                            console.log('[ suggestion ]-325', suggestion)
                            await postReviewIssuse({
                              projectId: form.value.project,
                              mrId: mergeId,
                              sha: merDetail.sha,
                              body: suggestion,
                              note: suggestion,
                              path: change.new_path,
                              line: lineObj.new_line,
                              line_type: 'new',
                              position: {
                                position_type: 'text',
                                ...lineObj,
                                new_path: change.new_path,
                                old_path: change.old_path,
                                base_sha: merDetail.sha,

                                start_sha: merDetail.sha,
                                head_sha: merDetail.sha,
                                // ...mergeRequests.diff_refs,
                              },
                            })
                            await delay(1 * 1000)
                          }
                        } catch (e) {
                          if (e?.response?.status === 429) {
                            console.log('Too Many Requests, try again')
                            await delay(60 * 1000)
                            diffBlocks.push(item)
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          } else {
            // 存在merge request 直接合并
            mergeId = mergeRequests[0].iid
            // 通过deepseek 查看merge request 差异并进行代码审查
            const { data: merData } = await findMergeRequestChanges({
              projectId: form.value.project,
              mrId: mergeId,
            })

            // 集成硅基流动DeepSeek代码审查
            const deepSeekService = new DeepSeekService()
            // 整体notes
            const formattedDiff = deepSeekService.formatDiffData(merData)
            const reviewResult = await deepSeekService.requestCodeReview(formattedDiff)
            console.log('[ reviewResult ]-325', reviewResult)
            if (reviewResult) {
              reviewResults.value = reviewResult
              checklistVisible.value = true
              // await  postReviewComment({
              //     projectId: form.value.project,
              //     mrId: mergeId,
              //     body: reviewResult,
              //   })
              await postReviewIssuse({
                projectId: form.value.project,
                mrId: mergeId,
                mrId: mergeId,
                sha: merDetail.sha,
                body: reviewResult,
                note: reviewResult,
              })
            }

            active.value++
          }
          // 3. 合并操作
          try {
            const { data: merData } = await acceptMergeRequest({
              projectId: form.value.project,
              mrId: mergeId,
            })
          } catch (e) {
            ElMessage.error('有冲突异常，请手动')
          }
          active.value++

          // 4. 打tag
          // const { data: tags } = await findTagsByProject({
          //   projectId: form.value.project,
          // })
          // let maxTagNum = maxHotfixTag(tags)
          // console.log(maxTagNum)
          // await createTagByProject({
          //   projectId: form.value.project,
          //   tag_name: 'hotfix_' + versionNum.value + '_' + (maxTagNum * 1 + 1),
          //   ref: targetBranch[0].name,
          // })
          
          // 5. 触发Jenkins构建（仅在启用时）
          if (jenkinsConfig.enabled) {
            ElMessage.info('正在触发Jenkins构建...')
            // 将数字ID转换为字符串再查询
            const projectIdStr = String(form.value.project)
            const jobName = projectMap.get(projectIdStr) || 'contract-tenant-service-vue'
            console.log('[ projectMap.get(form.value.project) ]-236', jobName)
            
            const jenkinsService = new JenkinsService({
              jobName: jobName
            })
            
            try {
              const buildResult = await jenkinsService.triggerBuild(jobName)
            
            if (buildResult.success) {
              ElMessage.success('Jenkins构建已触发！')
            } else {
              ElMessage.warning('Jenkins构建触发失败，请手动触发')
            }
          } catch (jenkinsError) {
            console.error('Jenkins集成错误:', jenkinsError)
            ElMessage.warning('Jenkins构建触发失败，请检查配置或手动触发')
          }
          
          // 定义异步睡眠函数
          const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
          await sleep(1000)
          
          if (merData.changes_count) {
            ElMessage.success('合并成功！Jenkins构建已触发')
          }
          isLoading.value = false
        }
          // TODO boss 项目 无需hotfix 直接 可以 feature => development=>developmrnt_Testset
          // testSetVersion developmrnt_Testset 分支
          var mergenId = ''

          // TODO 打完正常tags BOSS 端 再继续 development = 》development_Testset
          // if (form.value.project === 148 && form.value.isTestSet === '1') {
          //   bossBranchName.value = form.value.testSetVersion
          // } else {
          //   bossBranchName.value = ''
          // }
        }
      } catch (e) {
        console.log('[ e ]-288', e)
        isLoading.value = false
      }
    } else {
      isLoading.value = false
    }
  })
}

onMounted(() => {
  getProjects()
})
</script>

<style lang="scss" scoped>
.el-checkbox + .el-checkbox {
  margin-top: 20px;
  margin-left: 0;
}
.el-checkbox {
  display: block;
}
.step-wrap {
  margin-bottom: 30px;
  padding: 10px;
  text-align: center;
}
.footer {
  text-align: center;
}
</style>
